#ifndef __M_BINDING_H__
#define __M_BINDING_H__

#include "../mqcommon/mq_logger.hpp" // 包含你的日志头文件（提供 DLOG/ILOG/ELOG）
#include "../mqcommon/mq_helper.hpp"
#include "../mqcommon/mq_msg.pb.h"
#include <iostream>
#include <unordered_map>
#include <mutex>
#include <memory>
#include <string>

namespace zdfmq
{

    /**
     * 绑定关系模型：表示交换机与队列之间的绑定
     */
    struct Binding
    {
        using ptr = std::shared_ptr<Binding>;

        std::string exchange_name; // 绑定的交换机名称
        std::string msgqueue_name; // 绑定的队列名称
        std::string binding_key;   // 绑定键（用于路由消息）

        Binding() = default;
        Binding(const std::string &ename, const std::string &qname, const std::string &key)
            : exchange_name(ename), msgqueue_name(qname), binding_key(key) {}
    };

    /**
     * 绑定关系数据结构：
     * - MsgQueueBindingMap：单个交换机下的队列绑定（队列名 → 绑定信息）
     * - BindingMap：所有交换机的绑定信息（交换机名 → MsgQueueBindingMap）
     */
    using MsgQueueBindingMap = std::unordered_map<std::string, Binding::ptr>;
    using BindingMap = std::unordered_map<std::string, MsgQueueBindingMap>;

    /**
     * 绑定关系持久化层：负责与SQLite数据库交互
     */
    class BindingMapper
    {
    public:
        BindingMapper(const std::string &dbfile) : _sql_helper(dbfile)
        {
            // 创建数据库目录（若不存在）
            std::string path = FileHelper::parentDirectory(dbfile);
            if (!FileHelper::createDirectory(path))
            {
                ELOG("Failed to create database directory: %s", path.c_str());
            }
            _sql_helper.open();
            createTable(); // 确保表结构存在
        }

        // 创建绑定表（含联合主键，避免重复绑定）
        void createTable()
        {
            std::stringstream sql;
            sql << "create table if not exists binding_table("
                << "exchange_name varchar(64), "                  // 放宽长度限制
                << "msgqueue_name varchar(64), "                  // 放宽长度限制
                << "binding_key varchar(256), "                   // 支持更长的绑定键
                << "primary key(exchange_name, msgqueue_name));"; // 联合主键确保唯一
            if (!_sql_helper.exec(sql.str(), nullptr, nullptr))
            {
                ELOG("Failed to create binding_table!");
                assert(false); // 建表失败终止程序
            }
        }

        // 删除表中所有记录（保留表结构）
        void removeAllRecords()
        {
            std::lock_guard<std::mutex> lock(_db_mutex);
            std::string sql = "delete from binding_table;";
            if (!_sql_helper.exec(sql, nullptr, nullptr))
            {
                ELOG("Failed to clear binding_table records");
            }
        }

        // 删除整个表（谨慎使用，会丢失表结构）
        void removeTable()
        {
            std::lock_guard<std::mutex> lock(_db_mutex);
            std::string sql = "drop table if exists binding_table;";
            _sql_helper.exec(sql, nullptr, nullptr);
        }

        // 插入绑定记录（仅当不存在时）
        bool insert(Binding::ptr &binding)
        {
            std::lock_guard<std::mutex> lock(_db_mutex); // 确保线程安全

            // 简单SQL转义（防止注入和特殊字符问题）
            std::string ename = escapeSQL(binding->exchange_name);
            std::string qname = escapeSQL(binding->msgqueue_name);
            std::string key = escapeSQL(binding->binding_key);

            std::stringstream sql;
            sql << "insert or ignore into binding_table values('" // 已存在则忽略
                << ename << "', '" << qname << "', '" << key << "');";
            return _sql_helper.exec(sql.str(), nullptr, nullptr);
        }

        // 删除指定交换机+队列的绑定
        void remove(const std::string &ename, const std::string &qname)
        {
            std::lock_guard<std::mutex> lock(_db_mutex);
            std::string sql = "delete from binding_table where "
                              "exchange_name='" +
                              escapeSQL(ename) + "' and "
                                                 "msgqueue_name='" +
                              escapeSQL(qname) + "';";
            _sql_helper.exec(sql, nullptr, nullptr);
        }

        // 删除指定交换机的所有绑定
        void removeExchangeBindings(const std::string &ename)
        {
            std::lock_guard<std::mutex> lock(_db_mutex);
            std::string sql = "delete from binding_table where "
                              "exchange_name='" +
                              escapeSQL(ename) + "';";
            _sql_helper.exec(sql, nullptr, nullptr);
        }

        // 删除指定队列的所有绑定
        void removeMsgQueueBindings(const std::string &qname)
        {
            std::lock_guard<std::mutex> lock(_db_mutex);
            std::string sql = "delete from binding_table where "
                              "msgqueue_name='" +
                              escapeSQL(qname) + "';";
            _sql_helper.exec(sql, nullptr, nullptr);
        }

        // 从数据库恢复所有绑定关系到内存
        BindingMap recovery()
        {
            BindingMap result;
            std::string sql = "select exchange_name, msgqueue_name, binding_key from binding_table;";
            _sql_helper.exec(sql, selectCallback, &result);
            return result;
        }

    private:
        // 回调函数：解析查询结果到内存映射
        static int selectCallback(void *arg, int numcol, char **row, char **fields)
        {
            if (numcol < 3 || !row[0] || !row[1] || !row[2])
            {
                ELOG("Invalid binding record in database (skipped)");
                return 0; // 跳过无效记录
            }

            BindingMap *result = static_cast<BindingMap *>(arg);
            Binding::ptr bp = std::make_shared<Binding>(row[0], row[1], row[2]);

            // 插入内存映射（自动创建层级结构）
            (*result)[bp->exchange_name][bp->msgqueue_name] = bp;
            return 0;
        }

        // 简单SQL转义（防止注入和特殊字符问题）
        std::string escapeSQL(const std::string &str)
        {
            std::string res;
            for (char c : str)
            {
                if (c == '\'')
                    res += "''"; // 单引号转义
                else
                    res += c;
            }
            return res;
        }

    private:
        mutable std::mutex _db_mutex; // 数据库操作锁（确保线程安全）
        SqliteHelper _sql_helper;     // SQLite操作工具
    };

    /**
     * 绑定关系管理类（业务逻辑层）
     */
    class BindingManager
    {
    public:
        using ptr = std::shared_ptr<BindingManager>;

        BindingManager(const std::string &dbfile) : _mapper(dbfile)
        {
            _bindings = _mapper.recovery(); // 从数据库加载初始数据
            ILOG("Loaded %zu bindings from database", size());
        }

        // 绑定交换机与队列（durable=true时持久化）
        bool bind(const std::string &ename, const std::string &qname,
                  const std::string &key, bool durable)
        {
            std::unique_lock<std::mutex> lock(_mutex);

            // 检查是否已存在绑定
            if (existsUnsafe(ename, qname))
            {
                DLOG("Binding already exists: %s -> %s", ename.c_str(), qname.c_str());
                return true;
            }

            // 创建新绑定
            Binding::ptr bp = std::make_shared<Binding>(ename, qname, key);

            // 持久化处理（仅当需要时）
            if (durable)
            {
                if (!_mapper.insert(bp))
                {
                    ELOG("Failed to persist binding: %s -> %s", ename.c_str(), qname.c_str());
                    return false;
                }
            }

            // 更新内存映射
            _bindings[ename][qname] = bp;
            DLOG("Created binding: %s -> %s (key: %s)", ename.c_str(), qname.c_str(), key.c_str());
            return true;
        }

        // 解除单个绑定关系
        void unbind(const std::string &ename, const std::string &qname) // 修正函数名大小写
        {
            std::unique_lock<std::mutex> lock(_mutex);

            if (!existsUnsafe(ename, qname))
            {
                DLOG("Binding not found: %s -> %s", ename.c_str(), qname.c_str());
                return;
            }

            // 从数据库删除（若存在）
            _mapper.remove(ename, qname);

            // 从内存删除
            _bindings[ename].erase(qname);
            if (_bindings[ename].empty())
            {
                _bindings.erase(ename); // 清理空交换机的映射
            }
            DLOG("Removed binding: %s -> %s", ename.c_str(), qname.c_str());
        }

        // 删除指定交换机的所有绑定
        void removeExchangeBindings(const std::string &ename)
        {
            std::unique_lock<std::mutex> lock(_mutex);

            auto it = _bindings.find(ename);
            if (it == _bindings.end())
                return;

            // 数据库删除
            _mapper.removeExchangeBindings(ename);

            // 内存删除
            size_t cnt = it->second.size();
            _bindings.erase(it);
            ILOG("Removed %zu bindings for exchange: %s", cnt, ename.c_str());
        }

        // 删除指定队列的所有绑定
        void removeMsgQueueBindings(const std::string &qname)
        {
            std::unique_lock<std::mutex> lock(_mutex);
            size_t removed = 0;

            // 遍历所有交换机，删除关联的队列绑定
            for (auto it = _bindings.begin(); it != _bindings.end();)
            {
                if (it->second.erase(qname))
                {
                    removed++;
                }
                // 清理空交换机
                if (it->second.empty())
                {
                    it = _bindings.erase(it);
                }
                else
                {
                    ++it;
                }
            }

            // 数据库删除
            if (removed > 0)
            {
                _mapper.removeMsgQueueBindings(qname);
                ILOG("Removed %zu bindings for queue: %s", removed, qname.c_str());
            }
        }

        // 获取指定交换机的所有绑定（返回拷贝，避免外部修改）
        MsgQueueBindingMap getExchangeBindings(const std::string &ename)
        {
            std::unique_lock<std::mutex> lock(_mutex);
            auto it = _bindings.find(ename);
            return (it != _bindings.end()) ? it->second : MsgQueueBindingMap();
        }

        // 获取指定交换机+队列的绑定（返回智能指针）
        Binding::ptr getBinding(const std::string &ename, const std::string &qname)
        {
            std::unique_lock<std::mutex> lock(_mutex);
            return getBindingUnsafe(ename, qname);
        }

        // 检查绑定是否存在
        bool exists(const std::string &ename, const std::string &qname)
        {
            std::unique_lock<std::mutex> lock(_mutex);
            return existsUnsafe(ename, qname);
        }

        // 获取绑定总数
        size_t size()
        {
            std::unique_lock<std::mutex> lock(_mutex);
            size_t total = 0;
            for (const auto &pair : _bindings)
            {
                total += pair.second.size();
            }
            return total;
        }

        // 清空所有绑定（保留表结构）
        void clear()
        {
            std::unique_lock<std::mutex> lock(_mutex);
            _mapper.removeAllRecords(); // 删除所有记录（不删表）
            _bindings.clear();
            ILOG("All bindings cleared");
        }

    private:
        // 无锁版本：检查绑定是否存在（内部调用，需确保已加锁）
        bool existsUnsafe(const std::string &ename, const std::string &qname)
        {
            auto eit = _bindings.find(ename);
            if (eit == _bindings.end())
                return false;
            return eit->second.count(qname) > 0;
        }

        // 无锁版本：获取绑定（内部调用，需确保已加锁）
        Binding::ptr getBindingUnsafe(const std::string &ename, const std::string &qname)
        {
            auto eit = _bindings.find(ename);
            if (eit == _bindings.end())
                return nullptr;

            auto qit = eit->second.find(qname);
            return (qit != eit->second.end()) ? qit->second : nullptr;
        }

    private:
        mutable std::mutex _mutex; // 线程安全锁
        BindingMapper _mapper;     // 持久化层
        BindingMap _bindings;      // 内存绑定关系映射
    };

} // namespace zdfmq

#endif // __M_LOG_H__